package com.hitqz.robot.camera.thread;

import com.hitqz.robot.camera.entity.ConstantsFace;
import com.hitqz.robot.camera.entity.HikVisionErrorCode;
import com.hitqz.robot.camera.service.HCNetSDK;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;


/**
 * @Author: jiangxin14
 * @Date: 2024-08-07  15:12
 */
@Slf4j
public class AudioG711EncoderThread implements Runnable{

    private final int lVoiceComHandle; // 假设这是您的声音通信句柄
    private final String pcmName;

    public AudioG711EncoderThread(int handle,String pcmName) {
        this.lVoiceComHandle = handle;
        this.pcmName = pcmName;
    }


    @Override
    public void run() {
                    // 执行线程任务
                    HCNetSDK hCNetSDK = ConstantsFace.HK_NET_SDK;
                    FileInputStream Voicefile = null;
                    //FileOutputStream Encodefile = null;
                    int dataLength = 0;
                    try {
                        //创建从文件读取数据的FileInputStream流
                        Voicefile = new FileInputStream(new File(System.getProperty("user.dir") + File.separator+"pcm"+File.separator+pcmName+".pcm"));
                    } catch (FileNotFoundException e) {
                        log.error("[HK]pcm file:{},no found", pcmName);
                        return;
                    }
                    try {
                        //返回文件的总字节数
                        dataLength = Voicefile.available();
                    } catch (IOException e1) {
                        log.error("[HK]get file:{} length error:{}", pcmName,e1.getMessage());
                        return;
                    }
                    if (dataLength < 0) {
                        log.warn("[HK]file:{} dataSize < 0", pcmName);
                        return;
                    }
                    HCNetSDK.BYTE_ARRAY ptrVoiceByte = new HCNetSDK.BYTE_ARRAY(dataLength);
                    try {
                        Voicefile.read(ptrVoiceByte.byValue);
                    } catch (IOException e2) {
                        log.error("[HK]read file data error,{}",e2.getMessage());
                    }
                    ptrVoiceByte.write();
                    int iEncodeSize = 0;
                    HCNetSDK.NET_DVR_AUDIOENC_INFO enc_info = new HCNetSDK.NET_DVR_AUDIOENC_INFO();
                    enc_info.write();
                    Pointer pEncHandleG711 = hCNetSDK.NET_DVR_InitG711Encoder(enc_info.getPointer());
                    while ((dataLength - iEncodeSize) > 640) {
                        HCNetSDK.BYTE_ARRAY ptrPcmData = new HCNetSDK.BYTE_ARRAY(640);
                        System.arraycopy(ptrVoiceByte.byValue, iEncodeSize, ptrPcmData.byValue, 0, 640);
                        ptrPcmData.write();

                        HCNetSDK.BYTE_ARRAY ptrG711Data = new HCNetSDK.BYTE_ARRAY(320);
                        ptrG711Data.write();

                        HCNetSDK.NET_DVR_AUDIOENC_PROCESS_PARAM struEncParam = new HCNetSDK.NET_DVR_AUDIOENC_PROCESS_PARAM();
                        struEncParam.in_buf = ptrPcmData.getPointer();
                        struEncParam.out_buf = ptrG711Data.getPointer();
                        struEncParam.out_frame_size = 320;
                        //todo 改成灵活配置的，或者先去获取再自动设置进来
                        struEncParam.g711_type = 1;//G711编码类型：0- U law，1- A law
                        struEncParam.write();

                        if (!hCNetSDK.NET_DVR_EncodeG711Frame(pEncHandleG711, struEncParam)) {
                            log.info("[HK]NET_DVR_EncodeG711Frame failed, error code:{}", HikVisionErrorCode.getDescriptionFromCode(hCNetSDK.NET_DVR_GetLastError()));
                            hCNetSDK.NET_DVR_ReleaseG711Encoder(pEncHandleG711);
                            //	hCNetSDK.NET_DVR_StopVoiceCom(lVoiceHandle);
                            return;
                        }
                        struEncParam.read();
                        ptrG711Data.read();

                        long offsetG711 = 0;
                        ByteBuffer buffersG711 = struEncParam.out_buf.getByteBuffer(offsetG711, struEncParam.out_frame_size);
                        byte[] bytesG711 = new byte[struEncParam.out_frame_size];
                        buffersG711.rewind();
                        buffersG711.get(bytesG711);

                        iEncodeSize += 640;
                        log.debug("[HK]{}.pcm 编码字节数:{}" ,pcmName, iEncodeSize);
                        for (int i = 0; i < struEncParam.out_frame_size / 160; i++) {
                            HCNetSDK.BYTE_ARRAY ptrG711Send = new HCNetSDK.BYTE_ARRAY(160);
                            System.arraycopy(ptrG711Data.byValue, i * 160, ptrG711Send.byValue, 0, 160);
                            ptrG711Send.write();
                            if (!hCNetSDK.NET_DVR_VoiceComSendData(lVoiceComHandle, ptrG711Send.byValue, 160)) {
                                log.debug("[HK]NET_DVR_VoiceComSendData failed, error code:{}", HikVisionErrorCode.getDescriptionFromCode(hCNetSDK.NET_DVR_GetLastError()));
                            }

                            //需要实时速率发送数据
                            try {
                                Thread.sleep(20);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                }
    }

